package com.gc.ip.util;

import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

import javax.swing.text.JTextComponent;

public class IntegerKeyListener extends KeyAdapter
{
	private int min = 0;
	private int max = 0;
	
	public IntegerKeyListener(int min, int max)
	{
		this.min = min;
		this.max = max;
	}
	
	public IntegerKeyListener()
	{
		this(0, Integer.MAX_VALUE);
	}
	
	@Override
	public void keyTyped(KeyEvent e) 
	{
		validateInput(e);
	}
	
	private void validateInput(KeyEvent e)
	{
		char ch = e.getKeyChar();
		
		//consume if not digit
		if(!Character.isDigit(ch))
		{
			e.consume();
			return;
		}			
		String typedText = getTypedText((JTextComponent)e.getComponent(), ch);
		
		int val = 0;
		try
		{
			val = Integer.parseInt(typedText);
		}
		catch(NumberFormatException e2)
		{
			e.consume();
			return;
		}
		
		//out of range
		if(val < min || val > max)
		{
			e.consume();
			return;
		}
	}
	
	public static String getTypedText(JTextComponent textComp, char typedChar)
	{
		StringBuilder sb = new StringBuilder();
		
		do
		{
			String fullText = textComp.getText();
			
			//empty text in original text component
			if(fullText == null || fullText.isEmpty())
			{
				sb.append(typedChar);
				break;
			}
			
			int selStart = textComp.getSelectionStart();
			int selEnd = textComp.getSelectionEnd();
			
			//has selection text, replace the selection text with the typedChar
			if(selStart != selEnd)
			{
				sb.append(fullText.substring(0, selStart));
				sb.append(typedChar);
				sb.append(fullText.substring(selEnd));
				break;
			}
			
			//no selection text, insert the typedChar into the caret
			int caretPos = textComp.getCaretPosition();
			
			//if the caret is at the end
			if(caretPos >= fullText.length())
			{
				sb.append(fullText).append(typedChar);
			}
			else
			{
				sb.append(fullText.substring(0, caretPos));
				sb.append(typedChar);
				sb.append(fullText.substring(caretPos));
			}
		}
		while(false);
		
		return sb.toString();
	}
}
